package com.av.rmi;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import org.apache.log4j.Logger;

import com.av.exceptions.AvException;

/**
 * Clase que contiene los parametros necesarios para la ejecucion de cualquier
 * accion
 * 
 * @author Victor J Morales R
 * 
 */
public class Parametro implements Serializable {

	private static final long serialVersionUID = 1L;
	private static Logger log = Logger.getLogger(Parametro.class);

	public static enum Tipo {
		INPUT, OUTPUT
	}

	private String accion;
	private String username;
	private Map<Tipo, Object> valores;

	public Parametro() {
		super();

		valores = new HashMap<Tipo, Object>();
	}// Parametro

	public void setAccion(String accion) throws AvException {
		if (!CatalogoAcciones.contains(accion)) {
			throw new AvException("Accion no registrada en el catalogo");
		}

		this.accion = accion;
	}// setAccion

	public String getAccion() {
		return accion;
	}// getAccion

	public void setUsername(String username) {
		this.username = username;
	}// setUsername

	public String getUsername() {
		return username;
	}// getUsername

	public void setValor(Tipo t, Object valor) {
		this.valores.put(t, valor);
	}// setValor

	public Object getValor(Tipo t) {
		return this.valores.get(t);
	}// getValor

	/**
	 * Metodo para comprimir parametros y reducir la carga del servidor
	 * 
	 * @param p
	 * @return
	 * @throws AvException
	 */
	public static byte[] comprimir(Parametro p) throws AvException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		GZIPOutputStream gos = null;
		ObjectOutputStream oos = null;

		try {
			gos = new GZIPOutputStream(baos);
			oos = new ObjectOutputStream(gos);
		} catch (IOException e) {
			log.error("Error al intentar crear los output streams");
			throw new AvException("Error al intentar crear los output streams",
					e);
		}

		if (oos != null) {
			try {
				oos.writeObject(p);
				gos.finish();
			} catch (IOException e) {
				log.error("Error intentar comprimir el parametro");
				throw new AvException("Error intentar comprimir el parametro",
						e);
			}
		}

		return baos != null ? baos.toByteArray() : null;
	}// comprimir

	/**
	 * Funcion para descomprimir un parametro
	 * 
	 * @param b
	 * @return
	 * @throws AvException
	 */
	public static Parametro descomprimir(byte[] b) throws AvException {
		ObjectInputStream ois = null;
		Parametro p = null;

		try {
			ois = new ObjectInputStream(new GZIPInputStream(
					new ByteArrayInputStream(b)));
		} catch (IOException e) {
			log.error("Error al intentar crear los input streams");
			throw new AvException("Error al intentar crear los input streams",
					e);
		}

		if (ois != null) {
			try {
				p = (Parametro) ois.readObject();
			} catch (IOException e) {
				log.error("Error al intentar leer el objeto");
				throw new AvException("Error al intentar leer el objeto", e);
			} catch (ClassNotFoundException e) {
				log.error("Clase no encontrada");
				throw new AvException("Clase no encontrada", e);
			}
		}

		return p;
	}// descomprimir

}// Parametro
